﻿/*
This file is part of Ingo Karstein's Web based PowerShell Console for SharePoint project

**Do not remove this comment**

Please see the project homepage at CodePlex:
  http://spwebpsconsole.codeplex.com/
  
The project is based upon my project "Web based PowerShell Console":
  http://webpsconsole.codeplex.com/

Please see my blog:
  http://ikarstein.wordpress.com

Licence: GPLv2
    Ingo Karstein's SharePoint 2010 Custom Ribbon Demo
    Copyright (C) 2011  Ingo Karstein, ikarstein@hotmail.com

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Management.Automation.Host;
using System.Text;

namespace ik.SharePoint2010.SPWebPSConsole
{
    public class Buffer
    {
        internal const int MAXROWS = 1000;
        internal const int MAXCELLS = 1000;

        private List<BufferRow> rows;
        private static BufferCell blank = new BufferCell
                    {
                        BackgroundColor = ConsoleColor.Black,
                        ForegroundColor = ConsoleColor.White,
                        BufferCellType = BufferCellType.Complete,
                        Character = ' '
                    };

        public Buffer()
        {
            rows = new List<BufferRow>();
        }

        public int MaxRows
        {
            get
            {
                return MAXROWS;
            }
        }

        public int MaxCells
        {
            get
            {
                return MAXCELLS;
            }
        }

        public void ScrollLinesUp(int linecount)
        {
            for( int i = 0; i < linecount; i++ )
            {
                rows.RemoveAt(0);
            }
        }

        public string ToHtml()
        {
            StringBuilder sb = new StringBuilder(Buffer.MAXROWS * Buffer.MAXCELLS * 10);
            StringBuilder collectEmptyLines = new StringBuilder();
            sb.Append(@"<span class=""ConsoleLine"" style=""background-color:black;color:white;"">");
            ConsoleColor bc = ConsoleColor.Black;
            ConsoleColor fc = ConsoleColor.White;
            StringBuilder lineHtml = new StringBuilder(Buffer.MAXCELLS * 10);
            StringBuilder linePlain = new StringBuilder(Buffer.MAXCELLS);

            for( int i = 0; i < rows.Count; i++ )
            {
                BufferRow r = rows[i];

                lineHtml = new StringBuilder(Buffer.MAXCELLS * 10);
                linePlain = new StringBuilder(Buffer.MAXCELLS);

                int lastChar = -1;
                for( int j = 0; j < r.cells.Count; j++ )
                {
                    if( r.cells[j].Character != ' ' && r.cells[j].BufferCellType == BufferCellType.Complete )
                    {
                        lastChar = j;
                    }
                }
                if( lastChar > -1 )
                {
                    for( int j = 0; j <= lastChar; j++ )
                    {
                        BufferCell c = rows[i].cells[j];

                        if( c.BackgroundColor != bc || c.ForegroundColor != fc )
                        {
                            bc = c.BackgroundColor;
                            fc = c.ForegroundColor;
                            lineHtml.Append("</span>");
                            lineHtml.Append(string.Format(@"<span class=""ConsoleLine"" style=""background-color:{0};color:{1};"">", System.Drawing.ColorTranslator.ToHtml(bc.ToColor()), System.Drawing.ColorTranslator.ToHtml(fc.ToColor())));
                        }

                        lineHtml.Append(( c.Character == ' ' ? "&nbsp;" : c.Character.HtmlEncode() ));
                        linePlain.Append(c.Character);
                    }

                    string lPlain = linePlain.ToString();

                    if( !string.IsNullOrEmpty(lPlain.Trim()) )
                    {
                        sb.Append(collectEmptyLines.ToString());
                        collectEmptyLines = new StringBuilder();
                        sb.Append(lineHtml.ToString());
                        sb.Append("<br/>");
                    }
                    else
                        collectEmptyLines.Append("<br/>");
                }
                else
                {
                    collectEmptyLines.Append("<br/>");
                }
            }

            return sb.ToString();
        }

        internal BufferCell[,] GetBufferRect(Rectangle bufferRect)
        {
            BufferCell[,] ret = new BufferCell[bufferRect.Right - bufferRect.Left, bufferRect.Bottom - bufferRect.Top];

            for( int x = bufferRect.Left; x <= bufferRect.Right; x++ )
            {
                for( int y = bufferRect.Top; y <= bufferRect.Bottom; y++ )
                {
                    if( y >= rows.Count || x >= rows[y].cells.Count )
                    {
                        ret[x - bufferRect.Left, y - bufferRect.Top] = blank;
                    }
                    else
                    {
                        ret[x - bufferRect.Left, y - bufferRect.Top] = rows[y].cells[x];
                    }

                }
            }

            return ret;
        }

        internal void SetCell(int x, int y, BufferCell val)
        {
            if( y >= rows.Count )
            {
                for( int i = rows.Count; i <= y; i++ )
                {
                    rows.Add(new BufferRow());
                }
            }
            BufferRow r = rows[y];
            if( x >= r.cells.Count )
            {
                for( int i = r.cells.Count; i <= x; i++ )
                {
                    r.cells.Add(blank);
                }
            }
            r.cells[x] = val;
        }

        private Size publicKnownSize = new Size(MAXCELLS, MAXROWS);

        public Size Size
        {
            get
            {
                return publicKnownSize;
            }
            set
            {
                publicKnownSize = value;
            }
        }
    }

    public class BufferRow
    {
        public List<BufferCell> cells;

        public BufferRow()
        {
            cells = new List<BufferCell>(Buffer.MAXCELLS);
        }
    }
}